#ifndef FASYS_FASYS_SSERVICE_SUBSCRIBE_MEHTOD_HPP
#define FASYS_FASYS_SSERVICE_SUBSCRIBE_MEHTOD_HPP

#include <fas/adv/json_rpc3/method.hpp>
#include "../ipublisher.hpp"
#include "../api/subscribe_json.hpp"
#include "../api/publish_json.hpp"
#include "tags.hpp"

namespace fasys{ namespace sservice{

namespace aa = ::fas::aop;
namespace ap = ::fas::pattern;
namespace ad = ::fas::adv;
namespace ajr = ::fas::adv::json_rpc3;
namespace aj = ::fas::json;

struct subscribe_method
{
  const char *name() const { return "subscribe"; }

  typedef fasys::api::subscribe_json invoke_notify;
  typedef fasys::api::subscribe_json invoke_request;
  typedef aj::array<fasys::api::publish_json> invoke_response;
  

  typedef fasys::api::publish_json call_notify;
  /*typedef message_json call_request;
  typedef message_json call_response;
  */

  
  typedef fasys::api::subscribe_json::target request_type;
  typedef invoke_response::target response_type;
  
  subscribe_method()
    //: subscriptions(0)
  {
  }

  template<typename T>
  void clear(T&) 
  {
  }

  // ipublisher* publisher;
//  isubscriptions* subscriptions;

  template<typename T>
  bool request(T& t, request_type& cmd, int id, response_type& result )
  {
    /*
    std::cout << "yo!! sservice: PUBLISH METHOD " << id << std::endl;
    // publisher->publish(cmd);
    result = true;
    */
    /*
    virtual void subscribe(const std::string& key, const std::string& uuid, isubscriber*) = 0;
    virtual void describe(const std::string& key, const std::string& uuid, isubscriber*) = 0;
    */

    t.subscriptions->subscribe(t.key, t.uuid, &t);
    //const char error[] = "{\"jsonrpc\": \"2.0\", \"error\": {\"code\": -32700, \"message\": \"Parse error\"}, \"id\": null}";
    //t.get_aspect().template get<ajr::_invoke_>().error(t, id, error, sizeof(error) );
    return false;
    //return true;
    //return true;
  }

  template<typename T>
  void notify(T& t, request_type& cmd )
  {
    t.subscriptions->subscribe(t.key, t.uuid, &t);
    /*
    std::cout << "yo!! sservice: PUBLISH METHOD" << std::endl;
    publisher->publish(cmd);
    t.get_aspect().template get<ajr::_writer_>()(t, (const char*)(0), size_t(0) );
    */
  }
};

typedef aa::tag_list_n<
  aa::tag<_subscribe_>,
  aa::gtag< ajr::_gmethod_ >,
  aa::gtag< ad::_cleaner_ >
>::type subscribe_method_tag_list;

struct subscribe_method_advice
  : aa::advice<
      subscribe_method_tag_list,
      ajr::method<subscribe_method>
    >
{};

}}

#endif
